package com.plus.utils;

import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.alibaba.fastjson.JSON;
import org.springframework.util.StringUtils;

import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

/**
 * @program: springboot-future
 * @ClassName AESUtil
 * @description:
 * AES是一种对称加密，所谓对称加密就是加密与解密使用的秘钥是一个。
 * 最常用的模式就是 ECB模式 和 CBC 模式，当然还有很多其它模式，他们都属于AES加密。ECB模式和CBC模式俩者区别就是ECB不需要iv偏移量，而CBC需要。
 * 秘钥必须为16字节或者16字节的倍数的字节型数据。
 * 明文必须为16字节或者16字节的倍数的字节型数据，如果不够16字节需要进行补全。
 * @author: AI
 * @create: 2024-01-22 11:26
 * @Version 1.0
 **/
public class AESUtil {

    /**
     * 16字节
     */
    private static final String ENCRYPT_TYPE = "AES";

    private static final String ENCODE_KEY = "._^BV67nW6ck8fwg";
    private static final String IV_KEY = "b9vLgzQUUGgUbsef";

    public static void main(String[] args) {
        String encryptData = encryptFromString("加密123abc", "eEpG6Z2pIum6CWNB","x99KQTswVJk7JwZI",Mode.CBC, Padding.ZeroPadding);
        System.out.println("加密：" + encryptData);
        String decryptData = decryptFromString(encryptData, "eEpG6Z2pIum6CWNB","x99KQTswVJk7JwZI",Mode.CBC, Padding.ZeroPadding);
        System.out.println("解密：" + decryptData);
    }

    /**
     * 加密
     * @param data
     * @param mode
     * @param padding
     * @return
     */
    public static String encryptFromString(String data, String secrectKey,String ivKey, Mode mode, Padding padding) {
        AES aes;
        if(StringUtils.isEmpty(secrectKey)){
            secrectKey = ENCODE_KEY;
        }
        if(StringUtils.isEmpty(ivKey)){
            ivKey = IV_KEY;
        }
        if (Mode.CBC == mode) {
            aes = new AES(mode, padding, new SecretKeySpec(secrectKey.getBytes(), ENCRYPT_TYPE), new IvParameterSpec(ivKey.getBytes()));
        } else {
            aes = new AES(mode, padding, new SecretKeySpec(secrectKey.getBytes(), ENCRYPT_TYPE));
        }
        return aes.encryptBase64(data, StandardCharsets.UTF_8);
    }


    /**
     * 解密
     * @param data
     * @param mode
     * @param padding
     * @return
     */
    public static String decryptFromString(String data, String secrectKey,String ivKey, Mode mode, Padding padding) {
        AES aes;
        if(StringUtils.isEmpty(secrectKey)){
            secrectKey = ENCODE_KEY;
        }
        if(StringUtils.isEmpty(ivKey)){
            ivKey = IV_KEY;
        }
        if (Mode.CBC == mode) {
            aes = new AES(mode, padding, new SecretKeySpec(secrectKey.getBytes(), ENCRYPT_TYPE), new IvParameterSpec(ivKey.getBytes()));
        } else {
            aes = new AES(mode, padding, new SecretKeySpec(secrectKey.getBytes(), ENCRYPT_TYPE));
        }
        byte[] decryptDataBase64 = aes.decrypt(data);
        return new String(decryptDataBase64, StandardCharsets.UTF_8);
    }

    /**
     * 加密
     * @param obj
     * @return
     */
    public static String encode(Object obj) {
        String objStr = JSON.toJSONString(obj);
        String encode = SecureUtil.aes(ENCODE_KEY.getBytes()).encryptHex(objStr);
        return encode;
    }

    /**
     * 解密
     * @param str
     * @return
     */
    public static byte[] decodeByte(String str) {
        String decryptStr = SecureUtil.aes(ENCODE_KEY.getBytes()).decryptStr(str);
        byte[] byBuffer = decryptStr.getBytes();
        return byBuffer;
    }


}
